home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / src / exampleCode / opengl / xlib / tline.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-08-02  |  13.5 KB  |  645 lines

  1. /*
  2.  * Copyright 1994, Silicon Graphics, Inc.
  3.  * All Rights Reserved.
  4.  *
  5.  * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
  6.  * the contents of this file may not be disclosed to third parties, copied or
  7.  * duplicated in any form, in whole or in part, without the prior written
  8.  * permission of Silicon Graphics, Inc.
  9.  *
  10.  * RESTRICTED RIGHTS LEGEND:
  11.  * Use, duplication or disclosure by the Government is subject to restrictions
  12.  * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
  13.  * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
  14.  * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
  15.  * rights reserved under the Copyright Laws of the United States.
  16.  */
  17. #include <GL/glx.h>
  18. #include <stdio.h>
  19. #include <string.h>
  20. #include <unistd.h>
  21. #include <stdlib.h>
  22. #include <X11/keysym.h>
  23.  
  24. static int RGB_SB_attributes[] = {
  25.     GLX_RGBA,
  26.     GLX_RED_SIZE, 1,
  27.     GLX_GREEN_SIZE, 1,
  28.     GLX_BLUE_SIZE, 1,
  29.     GLX_DEPTH_SIZE, 1,
  30.     GLX_STENCIL_SIZE, 1,
  31.     None,
  32. };
  33.  
  34. static int RGB_DB_attributes[] = {
  35.     GLX_RGBA,
  36.     GLX_RED_SIZE, 1,
  37.     GLX_GREEN_SIZE, 1,
  38.     GLX_BLUE_SIZE, 1,
  39.     GLX_DOUBLEBUFFER,
  40.     GLX_DEPTH_SIZE, 1,
  41.     GLX_STENCIL_SIZE, 1,
  42.     None,
  43. };
  44.  
  45. static int CI_SB_attributes[] = {
  46.     GLX_DEPTH_SIZE, 1,
  47.     GLX_STENCIL_SIZE, 1,
  48.     None,
  49. };
  50.  
  51. static int CI_DB_attributes[] = {
  52.     GLX_DOUBLEBUFFER,
  53.     GLX_DEPTH_SIZE, 1,
  54.     GLX_STENCIL_SIZE, 1,
  55.     None,
  56. };
  57.  
  58. #define SETCOLOR(x) if (rgb) glColor3fv(rgbMap[x]); else glIndexf(x)
  59.  
  60. enum {
  61.     BLACK = 0,
  62.     RED,
  63.     GREEN,
  64.     YELLOW,
  65.     BLUE,
  66.     MAGENTA,
  67.     CYAN,
  68.     WHITE
  69. };
  70.  
  71. #define COLOR_OFFSET    16
  72.  
  73. static float rgbMap[8][3] = {
  74.     {0, 0, 0},
  75.     {1, 0, 0},
  76.     {0, 1, 0},
  77.     {1, 1, 0},
  78.     {0, 0, 1},
  79.     {1, 0, 1},
  80.     {0, 1, 1},
  81.     {1, 1, 1}
  82. };
  83.  
  84. Display *dpy;
  85. Colormap cmap;
  86. Window window;
  87. int rgb = 1;
  88. int doubleBuf = 1;
  89. int W = 300;
  90. int H = 300;
  91.  
  92. static GLint indexBits;
  93. static long ci = YELLOW;
  94. static GLboolean dither = GL_TRUE;
  95. static GLboolean fragment = GL_FALSE;
  96. static GLboolean smoothModel = GL_TRUE;
  97. static long mode1, mode2;
  98. static int blending;
  99. static float size;
  100. static float pntA[3] = {-165, 0, -0.5};
  101. static float pntB[3] = {-60, 0, -0.5};
  102. static float pntC[3] = {-40, -50, -0.5};
  103. static float pntD[3] = {30, 60, -0.5};
  104. static float pntAAB[3] = {-150, 0, -0.5};
  105. static float pntABA[3] = {-140, 0, -0.5};
  106. static float pntABB[3] = {-120, 0, -0.5};
  107. static float pntBAA[3] = {-100, 0, -0.5};
  108. static float pntBAB[3] = {-80, 0, -0.5};
  109. static float pntBBA[3] = {-70, 0, -0.5};
  110. static float zrot = 0.0;
  111. static float dzrot = 0.0;
  112. static int stenciling = 0;
  113. static int depthtest = 1;
  114. static int alwayspass = 0;
  115. static int depthMask = 0;
  116.  
  117. static void SetUpColorMap(void)
  118. {
  119.     XColor *xc;
  120.     float color;
  121.     long i, j, cells;
  122.  
  123.     if (indexBits < 5) return;
  124.     
  125.     cells = 16;
  126.     xc = (XColor *) malloc(cells * sizeof(XColor));
  127.  
  128.     for (i = 0; i < 16; i++) {
  129.     xc[i].pixel = i + COLOR_OFFSET;
  130.     xc[i].red = i * 4369;
  131.     xc[i].green = i * 4369;
  132.     xc[i].blue = 0;
  133.     xc[i].flags = DoRed | DoGreen | DoBlue;
  134.     }
  135.     XStoreColors(dpy, cmap, xc, cells);
  136.  
  137.     free((void *) xc);
  138. }
  139.  
  140. static void Init(void)
  141. {
  142.     if (!rgb) {
  143.     glGetIntegerv(GL_INDEX_BITS, &indexBits);
  144.         SetUpColorMap();
  145.     }
  146.  
  147.     mode1 = 0;
  148.     mode2 = 0;
  149.     size = 1;
  150.  
  151.     glViewport(10, 10, W-20, H-20);
  152.     glMatrixMode(GL_PROJECTION);
  153.     glLoadIdentity();
  154.     glOrtho(-175, 175, -175, 175, -1, 1);
  155.     glMatrixMode(GL_MODELVIEW);
  156.  
  157. }
  158.  
  159. static void Redraw(void)
  160. {
  161.     long i;
  162.  
  163.     if (dzrot != 0.0) {
  164.     zrot += dzrot;
  165.     }
  166.  
  167.     glClearColor(0.0, 0.0, 0.0, 0.0);
  168.  
  169.     glClear(GL_COLOR_BUFFER_BIT);
  170.  
  171.     glLineWidth(3);
  172.     glDisable(GL_LINE_STIPPLE);
  173.     glDisable(GL_LINE_SMOOTH);
  174.     glDisable(GL_BLEND);
  175.  
  176.     if (depthtest) {
  177.     glClearDepth(1.0);
  178.     glClear(GL_DEPTH_BUFFER_BIT);
  179.     glEnable(GL_DEPTH_TEST);
  180.     if (alwayspass) {
  181.         glDepthFunc(GL_ALWAYS);
  182.     } else {
  183.         glDepthFunc(GL_LESS);
  184.     }
  185.  
  186.     SETCOLOR(MAGENTA);
  187.     glBegin(GL_LINES);
  188.     for (i = -8; i <= 8; i++) {
  189.         glVertex3f(i*20, -175, 0);
  190.         glVertex3f(i*20,  175, 0);
  191.     }
  192.     if (depthMask) {
  193.         glEnd();
  194.         glDepthMask(GL_FALSE);
  195.         glBegin(GL_LINES);
  196.     }
  197.     for (i = -8; i <= 8; i++) {
  198.         glVertex3f(-175, i*20, 0);
  199.         glVertex3f( 175, i*20, 0);
  200.     }
  201.     glEnd();
  202.     if (depthMask) {
  203.         glDepthMask(GL_TRUE);
  204.     }
  205.     }
  206.  
  207.     if (stenciling) {
  208.     SETCOLOR(BLACK);
  209.  
  210.         glClearStencil(0);
  211.         glClear(GL_STENCIL_BUFFER_BIT);
  212.  
  213.     glEnable(GL_STENCIL_TEST);
  214.         glStencilFunc(GL_ALWAYS, 1, 3);
  215.         glStencilOp(GL_KEEP, GL_INVERT, GL_REPLACE);
  216.  
  217.     glBegin(GL_LINES);
  218.     for (i = -10; i <= 10; i++) {
  219.         glVertex3f(i*17, -175, -0.5);
  220.         glVertex3f(i*17,  175, -0.5);
  221.     }
  222.     for (i = -10; i <= 10; i++) {
  223.         glVertex3f(-175, i*17, -0.5);
  224.         glVertex3f( 175, i*17, -0.5);
  225.     }
  226.     glEnd();
  227.  
  228.     glStencilOp(GL_KEEP, GL_KEEP, GL_INVERT);
  229.  
  230.     if (depthtest) {
  231.         SETCOLOR(RED);
  232.         glStencilFunc(GL_EQUAL, 3, 3);
  233.         glDisable(GL_DEPTH_TEST);
  234.         glBegin(GL_QUADS);
  235.         glVertex3f(-175, -175, -0.5);
  236.         glVertex3f(-175,  175, -0.5);
  237.         glVertex3f( 175,  175, -0.5);
  238.         glVertex3f( 175, -175, -0.5);
  239.         glEnd();
  240.         glEnable(GL_DEPTH_TEST);
  241.     }
  242.  
  243.     glStencilOp(GL_KEEP, GL_INVERT, GL_KEEP);
  244.     glStencilFunc(GL_NOTEQUAL, 1, 1);
  245.     }
  246.  
  247.     glLineWidth(size);
  248.     if (mode1) {
  249.     glEnable(GL_LINE_STIPPLE);
  250.     } else {
  251.     glDisable(GL_LINE_STIPPLE);
  252.     }
  253.     glLineStipple(1, 0xF0E0);
  254.     
  255.     if (blending) {
  256.     glEnable(GL_BLEND);
  257.     glBlendFunc(GL_SRC_ALPHA, GL_ZERO);
  258.     }
  259.  
  260.     if (mode2) {
  261.     glEnable(GL_LINE_SMOOTH);
  262.     if (mode2 > 1) {
  263.         glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
  264.     } else {
  265.         glHint(GL_LINE_SMOOTH_HINT, GL_DONT_CARE);
  266.     }
  267.     } else {
  268.     glDisable(GL_LINE_SMOOTH);
  269.     }
  270.  
  271.     glPushMatrix();
  272.     glRotatef(zrot, 0,0,1);
  273.     for (i = 0; i < 360; i += 5) {
  274.     glRotatef(5.0, 0,0,1);
  275.  
  276.     if (rgb) glColor3fv(rgbMap[YELLOW]); else glIndexi(ci);
  277.     glBegin(GL_LINE_STRIP);
  278.     if (fragment) {
  279.         glVertex3fv(pntA);
  280.         glVertex3fv(pntAAB);
  281.         glVertex3fv(pntABA);
  282.         glVertex3fv(pntABB);
  283.         if (rgb || !mode2) {
  284.         SETCOLOR(CYAN);
  285.         }
  286.         glVertex3fv(pntBAA);
  287.         glVertex3fv(pntBAB);
  288.         glVertex3fv(pntBBA);
  289.         glVertex3fv(pntB);
  290.     } else {
  291.         glVertex3fv(pntA);
  292.         if (rgb || !mode2) {
  293.         SETCOLOR(CYAN);
  294.         }
  295.         glVertex3fv(pntB);
  296.     }
  297.     glEnd();
  298.  
  299.     SETCOLOR(GREEN);
  300.     }
  301.     glPopMatrix();
  302.  
  303.     glFlush();
  304.  
  305.     if (depthtest) {
  306.     glDisable(GL_DEPTH_TEST);
  307.  
  308.     if (stenciling) {
  309.         SETCOLOR(WHITE);
  310.         glStencilFunc(GL_EQUAL, 3, 3);
  311.         glBegin(GL_QUADS);
  312.         glVertex3f(-175, -175, -0.5);
  313.         glVertex3f(-175,  175, -0.5);
  314.         glVertex3f( 175,  175, -0.5);
  315.         glVertex3f( 175, -175, -0.5);
  316.         glEnd();
  317.     }
  318.     }
  319.  
  320.     if (stenciling) {
  321.     glDisable(GL_STENCIL_TEST);
  322.     }
  323.  
  324.     if (doubleBuf) {
  325.     glXSwapBuffers(dpy, window);
  326.     }
  327. }
  328.  
  329. static void Usage(void)
  330. {
  331.     fprintf(stderr, "Usage: program [-c] [-s] [-geometry WxH+X+Y]\n");
  332.     fprintf(stderr, " -c  run in color index mode\n");
  333.     fprintf(stderr, " -s  run in singlebuffer mode\n");
  334.     fprintf(stderr, " -geometry   window size and location\n");
  335.     exit(1);
  336. }
  337.  
  338. static Bool WaitForMapNotify(Display *d, XEvent *e, char *arg)
  339. {
  340.     if ((e->type == MapNotify) && (e->xmap.window == (Window) arg)) {
  341.     return GL_TRUE;
  342.     }
  343.     return GL_FALSE;
  344. }
  345.  
  346. int main(int argc, char** argv)
  347. {
  348.     XVisualInfo *vi;
  349.     XSetWindowAttributes swa;
  350.     GLXContext cx;
  351.     XEvent event;
  352.     GLboolean needDisplay;
  353.     XColor black;
  354.     int i;
  355.     XSizeHints sizehints;
  356.     char *geometry = NULL;
  357.  
  358.     rgb = 1;
  359.     for (i = 1; i < argc; i++) {
  360.         if (argv[i][0] == '-') {
  361.         if (strcmp(argv[i], "-geometry") == 0) {
  362.         i++;
  363.         geometry = argv[i];
  364.         } else switch (argv[i][1]) {
  365.               case 'c':
  366.                 rgb = GL_FALSE;
  367.                 break;
  368.           case 's':
  369.         doubleBuf = 0;
  370.         break;
  371.               default:
  372.                 Usage();
  373.             }
  374.         } else {
  375.             Usage();
  376.         }
  377.     }
  378.  
  379.     dpy = XOpenDisplay(0);
  380.     if (!dpy) {
  381.     fprintf(stderr, "Can't connect to display \"%s\"\n", getenv("DISPLAY"));
  382.     return -1;
  383.     }
  384.  
  385.     vi = glXChooseVisual(dpy, DefaultScreen(dpy),
  386.         doubleBuf ? (rgb ? RGB_DB_attributes : CI_DB_attributes) :
  387.         (rgb ? RGB_SB_attributes : CI_SB_attributes));
  388.     if (!vi) {
  389.     fprintf(stderr, "No singlebuffered rgba visual on \"%s\"\n",
  390.         getenv("DISPLAY"));
  391.     return -1;
  392.     }
  393.  
  394.     sizehints.flags = PPosition | PSize;
  395.     sizehints.width = W;
  396.     sizehints.height = H;
  397.     sizehints.x = 10;
  398.     sizehints.y = 10;
  399.     if(geometry) {
  400.     int flags, x, y, width, height;
  401.  
  402.     flags = XParseGeometry(geometry, &x, &y,
  403.                    (unsigned int *)&width,
  404.                    (unsigned int *)&height);
  405.         if(WidthValue & flags) {
  406.         sizehints.flags |= USSize;
  407.         sizehints.width = width;
  408.         W = width;
  409.     }
  410.     if(HeightValue & flags) {
  411.         sizehints.flags |= USSize;
  412.         sizehints.height = height;
  413.         H = height;
  414.     }
  415.     if(XValue & flags) {
  416.         if(XNegative & flags)
  417.         x = DisplayWidth(dpy, DefaultScreen(dpy)) + x 
  418.             - sizehints.width;
  419.                 sizehints.flags |= USPosition;
  420.         sizehints.x = x;
  421.     }
  422.     if(YValue & flags) {
  423.         if(YNegative & flags)
  424.         y = DisplayHeight(dpy, DefaultScreen(dpy)) + y 
  425.             - sizehints.height;
  426.                 sizehints.flags |= USPosition;
  427.         sizehints.y = y;
  428.     }
  429.     }
  430.     cmap = XCreateColormap(dpy, RootWindow(dpy, vi->screen), vi->visual,
  431.                rgb ? AllocNone : AllocAll);
  432.  
  433.     if (!rgb) {
  434.     XColor buf;
  435.     int i;
  436.  
  437.     buf.flags = DoRed | DoGreen | DoBlue;
  438.  
  439.     /* Init color map */
  440.     for (i=0; i<16; i++) {
  441.         buf.pixel = i;
  442.         buf.blue = (i & 4) ? 65535 : 0;
  443.         buf.green = (i & 2) ? 65535 : 0;
  444.         buf.red = (i & 1) ? 65535 : 0;
  445.         if (i > 8) {
  446.         buf.red /= 2;
  447.         buf.green /= 2;
  448.         buf.blue /= 2;
  449.         }
  450.         XStoreColor(dpy, cmap, &buf);
  451.     }
  452.     }
  453.  
  454.     swa.border_pixel = 0;
  455.     swa.background_pixmap = None;
  456.     swa.colormap = cmap;
  457.     swa.event_mask = ExposureMask | StructureNotifyMask | KeyPressMask
  458.     | KeyReleaseMask;
  459.     window = XCreateWindow(dpy, RootWindow(dpy, vi->screen), 
  460.                sizehints.x, sizehints.y,
  461.                sizehints.width, sizehints.height,
  462.                0, vi->depth, InputOutput, vi->visual,
  463.                CWBackPixmap|CWBorderPixel|CWColormap|CWEventMask,
  464.                &swa);
  465.     XSetStandardProperties(dpy, window, "tline", "tline", None,
  466.                            argv, argc, &sizehints);
  467.     XSetWMColormapWindows(dpy, window, &window, 1);
  468.     XMapWindow(dpy, window);
  469.     XIfEvent(dpy, &event, WaitForMapNotify, (char*)window);
  470.  
  471.     cx = glXCreateContext(dpy, vi, 0, GL_TRUE);
  472.     if (!glXMakeCurrent(dpy, window, cx)) {
  473.     fprintf(stderr, "Can't make window current to context\n");
  474.     return -1;
  475.     }
  476.  
  477.     Init();
  478.  
  479.     needDisplay = GL_TRUE;
  480.     for (;;) {
  481.     if (XPending(dpy) || dzrot == 0.0) do {
  482.         XNextEvent(dpy, &event);
  483.         switch (event.type) {
  484.           case Expose:
  485.         needDisplay = GL_TRUE;
  486.         break;
  487.           case ConfigureNotify:
  488.         W = event.xconfigure.width;
  489.         H = event.xconfigure.height;
  490.         glViewport(10, 10, W-20, H-20);
  491.         glMatrixMode(GL_PROJECTION);
  492.         glLoadIdentity();
  493.         glOrtho(-175, 175, -175, 175, -1, 1);
  494.         glMatrixMode(GL_MODELVIEW);
  495.         needDisplay = GL_TRUE;
  496.         break;
  497.           case KeyPress:
  498.         {
  499.             char buf[100];
  500.             int rv;
  501.             KeySym ks;
  502.             GLboolean setNeed = GL_TRUE;
  503.  
  504.             rv = XLookupString(&event.xkey, buf, sizeof(buf), &ks, 0);
  505.             switch (ks) {
  506.               case XK_Escape:
  507.             exit(0);
  508.               case XK_Y:
  509.               case XK_y:
  510.             blending = 1-blending;
  511.             break;
  512.               case XK_G:
  513.               case XK_g:
  514.             if (dzrot != 0.0) {
  515.                 dzrot = 0.0;
  516.             } else {
  517.                 dzrot = 0.2;
  518.             }
  519.             break;
  520.               case XK_q:
  521.               case XK_Q:
  522.             mode1 = 1;
  523.             break;
  524.               case XK_w:
  525.               case XK_W:
  526.             mode1 = 0;
  527.             break;
  528.               case XK_e:
  529.               case XK_E:
  530.             mode2 = 2;
  531.             ci = COLOR_OFFSET;
  532.             break;
  533.               case XK_r:
  534.               case XK_R:
  535.             mode2 = 1;
  536.             ci = COLOR_OFFSET;
  537.             break;
  538.               case XK_t:
  539.               case XK_T:
  540.             mode2 = 0;
  541.             ci = YELLOW;
  542.             break;
  543.               case XK_a:
  544.               case XK_A:
  545.             if (mode2) {
  546.                 size += 0.25;
  547.             } else {
  548.                 size ++;
  549.             }
  550.             break;
  551.               case XK_z:
  552.               case XK_Z:
  553.             if (mode2) {
  554.                 size -= 0.25;
  555.             } else {
  556.                 size --;
  557.             }
  558.             if (size < 1) {
  559.                 size = 1;
  560.             }
  561.             break;
  562.               case XK_D:
  563.               case XK_d:
  564.             dither = !dither;
  565.             if (dither) {
  566.                 glEnable(GL_DITHER);
  567.                 printf("Dithering on\n");
  568.             } else {
  569.                 glDisable(GL_DITHER);
  570.                 printf("Dithering off\n");
  571.             }
  572.             break;
  573.               case XK_F:
  574.               case XK_f:
  575.             fragment = !fragment;
  576.             if (fragment) {
  577.                 printf("Fragmenting\n");
  578.             } else {
  579.                 printf("No fragmenting\n");
  580.             }
  581.             break;
  582.               case XK_S:
  583.               case XK_s:
  584.             smoothModel = !smoothModel;
  585.             if (smoothModel) {
  586.                 printf("Smooth shading\n");
  587.                 glShadeModel(GL_SMOOTH);
  588.             } else {
  589.                 printf("Flat shading\n");
  590.                 glShadeModel(GL_FLAT);
  591.             }
  592.             break;
  593.               case XK_X:
  594.               case XK_x:
  595.             stenciling = !stenciling;
  596.             if (stenciling) {
  597.                 printf("Stenciling\n");
  598.             } else {
  599.                 printf("Not stenciling\n");
  600.             }
  601.             break;
  602.               case XK_C:
  603.               case XK_c:
  604.             depthtest = !depthtest;
  605.             if (depthtest) {
  606.                 printf("Depth testing\n");
  607.             } else {
  608.                 printf("No depth testing\n");
  609.             }
  610.             break;
  611.               case XK_V:
  612.               case XK_v:
  613.             alwayspass = !alwayspass;
  614.             if (alwayspass) {
  615.                 printf("Always pass\n");
  616.             } else {
  617.                 printf("Not always pass\n");
  618.             }
  619.             break;
  620.               case XK_B:
  621.               case XK_b:
  622.             depthMask = !depthMask;
  623.             if (depthMask) {
  624.                 printf("Depth writes masked for horizontal lines\n");
  625.             } else {
  626.                 printf("Depth writes not masked\n");
  627.             }
  628.             break;
  629.               default:
  630.             setNeed = GL_FALSE;
  631.             break;
  632.             }
  633.             if (setNeed) needDisplay = GL_TRUE;
  634.         }
  635.         break;
  636.         }
  637.     } while (XPending(dpy) != 0);
  638.  
  639.     if (dzrot != 0.0 || needDisplay) {
  640.         needDisplay = GL_FALSE;
  641.         Redraw();
  642.     }
  643.     }
  644. }
  645.